package com.aisile.common.web.wemedia;

import com.aisile.model.common.dtos.ResponseResult;
import com.aisile.model.common.enums.AdminHttpCodeEnum;
import com.aisile.model.media.pojos.WmUser;
import com.aisile.model.user.pojos.ApUser;
import com.aisile.utils.common.AppJwtUtil;
import com.aisile.utils.threadlocal.AppThreadLocalUtils;
import com.aisile.utils.threadlocal.WmThreadLocalUtils;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Claims;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ComponentScan 可能扫不到 @WebFilter  这样写不把握
 * @Auther:yry
 * @Date:2024/7/15 0015
 * @VERSON:1.0
 */

@WebFilter(filterName = "wemediaTokenFilter", urlPatterns = "/*")
public class WemediaTokenFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 每次用户请求 我们都需要解析一次token
        // 获取用户信息  用户信息存那？用户信息要保存在 私有的线程的对象中
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        ResponseResult responseResult = null;
        // 先放行
        try {
            if (request.getRequestURI().contains("/login/in")) {
                filterChain.doFilter(request, response);
            } else {
                // 获取token  当前代码属于后端自行觉得 token存放问题 所以只需要在头信息中获取即可
                String token = request.getHeader("token");
                if (token == null || "".equals(token.trim())) {
                    // token为空 报错 当前是在 微服务中发生 所以需要返回和前端约定好的结构数据
                    responseResult = ResponseResult.errorResult(AdminHttpCodeEnum.TOKEN_REQUIRE);
                } else {
                    // token有 但是有可能被改过 或者过期
                    Claims claims = AppJwtUtil.getClaimsBody(token);
                    int i = AppJwtUtil.verifyToken(claims);
                    if (i > 0 || i < -1) {
                        // 有问题
                        responseResult = ResponseResult.errorResult(AdminHttpCodeEnum.TOKEN_INVALID);
                    } else {
                        //  - 1 0 有效 但是可能快过期了  并保存用户信息
                        WmUser wmUser = new WmUser();
                        Integer id = (Integer) claims.get("id");
                        wmUser.setId(id);
                        WmThreadLocalUtils.setUser(wmUser);

                        if (i == 0) {
                            // 续期  和前端约定好 响应头信息中 给他一个标识 refresh_token
                            response.setHeader("refresh_token", AppJwtUtil.getToken(id.longValue()));
                        }
                        // 放行
                        filterChain.doFilter(request, response);
                    }
                }

            }
        } catch (Exception e) {
            responseResult = ResponseResult.errorResult(AdminHttpCodeEnum.TOKEN_INVALID);
        } finally {
            if (responseResult != null) {
                response.setContentType("application/json");
                response.setCharacterEncoding("utf-8");
                response.getOutputStream().write(JSON.toJSONString(responseResult).getBytes());
            }
        }

    }
}
